home *** CD-ROM | disk | FTP | other *** search
- /* atie.c -- Ascii To Input Event */
-
- /* The contents of this file are copyright 1990, Mikael Karlsson.
- * You may use these routines freely in non-commerical programs,
- * provided that some notice of it's use is given in the program
- * and/or documentation.
- */
-
- #if __SASC
- #include "snap.h"
- #endif
-
- struct HalfMap {
- UBYTE *KeyMapTypes;
- ULONG *KeyMap;
- UBYTE *Capsable;
- UBYTE *Repeatable;
- };
-
- struct DeadSpec {
- UBYTE ds_Prev1DownCode;
- UBYTE ds_Prev1DownQual;
- UBYTE ds_Prev2DownCode;
- UBYTE ds_Prev2DownQual;
- };
-
- #define CONTROLBITS ((1 << 5) | (1 << 6))
- #define KEYMAPSIZE 64
-
- #define S IEQUALIFIER_LSHIFT
- #define A IEQUALIFIER_RALT
- #define C IEQUALIFIER_CONTROL
-
- /* These tables can be found in RKM Libraries & Devices 1.3 */
-
- WORD deadQuals[8][10] = {
- { KC_NOQUAL , 1, 0 },
- { KCF_SHIFT , 2, 0, S },
- { KCF_ALT , 2, 0, A },
- { KCF_ALT+KCF_SHIFT , 4, 0, S, A, S+A },
- { KCF_CONTROL , 2, 0, C },
- { KCF_CONTROL+ KCF_SHIFT , 4, 0, S, C, S+C },
- { KCF_CONTROL+KCF_ALT , 4, 0, A, C, A+C },
- { KCF_CONTROL+KCF_ALT+KCF_SHIFT , 8, 0, S, A, S+A, C, C+S, C+A, C+S+A }
- };
-
- WORD normalQuals[8][6] = {
- { KC_NOQUAL , 1, 0, 0, 0, 0 },
- { KCF_SHIFT , 2, 0, 0, S, 0 },
- { KCF_ALT , 2, 0, 0, A, 0 },
- { KCF_ALT+KCF_SHIFT , 4, S+A, A, S, 0 },
- { KCF_CONTROL , 2, 0, 0, C, 0 },
- { KCF_CONTROL+ KCF_SHIFT , 4, C+S ,C, S, 0 },
- { KCF_CONTROL+KCF_ALT , 4, C+A, C, A, 0 },
- { KCF_CONTROL+KCF_ALT+KCF_SHIFT , 4, S+A, A, S, 0 }
- };
-
- #define keytype 0
- #define combos 1
-
- #undef S
- #undef A
- #undef C
-
- STATIC WORD checkNormalQual(four_bytesp, val, type, qualp)
- LONG four_bytesp;
- UBYTE val;
- UWORD type;
- UWORD *qualp;
- {
- register UBYTE *p = (UBYTE *)four_bytesp; /* codes held in long word */
- register WORD position;
- register WORD i = normalQuals[type][combos];
-
- position = 4;
-
- while (i--) {
- --position;
- if (p[position] == val) {
- *qualp = normalQuals[type][position + 2];
- return 1;
- }
- }
- return 0;
- }
-
- WORD checkNormal(p, val, type, qualp)
- UBYTE *p;
- UBYTE val;
- WORD type;
- UWORD *qualp;
- {
- /* only one way to match a vanilla control key */
- if (type == KC_VANILLA && (val & CONTROLBITS) == NULL) { /* control vanilla */
- if (checkNormalQual(p, val | CONTROLBITS, type, qualp)) {
- *qualp |= IEQUALIFIER_CONTROL;
- return (1);
- } else {
- return (0);
- }
- } else { /* not a control */
- return (checkNormalQual(p, val, type, qualp));
- }
- }
-
-
- STATIC WORD checkDead(keybase, val, type, qualp, indexp)
- UBYTE *keybase; /* note: byte pointer */
- UBYTE val;
- WORD type;
- UWORD *qualp;
- ULONG *indexp;
- {
- WORD i;
- WORD j;
- register UBYTE *p = keybase; /* need to remember keybase for offsets */
- UBYTE *deadp;
-
- /* walk through two-byte entries, one for each qual. combo. */
- for (i = 0; i < deadQuals[type][combos]; ++i, p += 2) {
- switch (p[0]) {
- case DPF_DEAD: /* dead keys do not themselves map to anything */
- break;
- case DPF_MOD: /* dead key modifiable */
- deadp = keybase + p[1];
- /* look down the string indexed by dead-key index */
- for (j = 0; j < 6; ++j) {
- if (deadp[j] == val) {
- *qualp = deadQuals[type][i + 2];
- *indexp = j;
- return 1;
- }
- }
- break;
- case 0: /* normal stroke for this key */
- if (p[1] == val) {
- *qualp = deadQuals[type][i + 2];
- return 1;
- }
- }
- }
- return (0);
- }
-
- /*
- * Calculates Code+Qual of previous dead key (should be keys)
- * and puts them in DeapSpec.
- * returns success (1) or failure (0).
- */
- STATIC WORD BuildDeadSpec(inx, hm, hms, ds)
- ULONG inx;
- struct HalfMap *hm;
- WORD hms;
- struct DeadSpec *ds;
- {
- /* find keystroke which generates index */
-
- register WORD code = 0;
- register UBYTE *deadthing;
- register WORD i;
-
- do {
- /* check each deadkey in the table */
-
- if (hm->KeyMapTypes[code] & KCF_DEAD) {
- register WORD type = hm->KeyMapTypes[code] & 7;
-
- /* keymap entry is pointer to prefix:byte pairs */
-
- deadthing = (UBYTE *)hm->KeyMap[code];
- for (i = 0; i < deadQuals[type][combos]; ++i, deadthing += 2) {
- /* check for index prefix and correct index */
- if (deadthing[0] == DPF_DEAD &&
- (deadthing[1] & DP_2DINDEXMASK) == inx) {
- ds->ds_Prev1DownCode = code;
- ds->ds_Prev1DownQual = deadQuals[type][i + 2];
- ds->ds_Prev2DownCode = 0;
- ds->ds_Prev2DownQual = 0;
- return 1;
- }
- }
- }
- } while (++code < hms);
-
- return 0; /* Not found */
- }
-
- STATIC WORD checkString(keybase, val, type, qualp)
- UBYTE *keybase; /* note: byte pointer */
- UBYTE val;
- WORD type;
- UWORD *qualp;
- {
- WORD i;
- register UBYTE *p = keybase; /* need to remember keybase for offsets */
-
- /* walk through two-byte entries, one for each qual. combo. */
- for (i = 0; i < deadQuals[type][combos]; ++i, p += 2) {
- if (p[0] == 1) { /* One char in string */
- if (keybase[p[1]] == val) { /* Our char? */
- *qualp = deadQuals[type][i + 2];
- return 1;
- }
- }
- }
- return (0);
- }
-
- /* BuildEvent tries to generate an input event.
- * returns success (1) or failure (0).
- */
- STATIC UWORD BuildEvent(value, hm, hms, ie, km)
- register UBYTE value;
- struct HalfMap *hm;
- WORD hms;
- struct InputEvent *ie;
- struct KeyMap *km; /* We need this to find dead prefix */
- {
- register UWORD code = 0;
- register WORD type;
- register LONG *p; /* points to four-byte lokeymap entry */
- UWORD *qualp = &ie->ie_Qualifier;
- WORD found_it = 0;
- ULONG index = 0;
-
- p = (LONG *) hm->KeyMap;
-
- do {
- type = hm->KeyMapTypes[code];
- /* determine type of key */
- if (type & KCF_STRING) {
- found_it = checkString((UBYTE *)*p, value, type & 7, qualp);
- } else if (type & KCF_DEAD) {
- found_it = checkDead((UBYTE *)*p, value, type & 7, qualp, &index);
- } else if (!(type & KCF_NOP)) {
- found_it = checkNormal((LONG)p, value, type & 7, qualp);
- }
- ++p;
- } while (!found_it && ++code < hms);
-
- if (found_it) {
- ie->ie_Code = code;
- /* Successful BuildEvent. Check for dead key. */
- if (index) {
- struct HalfMap *dhm;
- struct DeadSpec *ds = (struct DeadSpec *)&ie->ie_EventAddress;
-
- dhm = (struct HalfMap *)&km->km_LoKeyMapTypes;
- if (BuildDeadSpec(index, dhm, 64, ds)) {
- return 1;
- }
- dhm = (struct HalfMap *)&km->km_HiKeyMapTypes;
- if (BuildDeadSpec(index, dhm, 56, ds)) {
- return 1;
- }
- return 0; /* Couldn't find index generating dead key */
- } else {
- return 1;
- }
- } else {
- return 0;
- }
- }
-
- /*
- * NAME
- * AsciiToInputEvent -- build input event to generate ascii
- *
- * SYNOPSIS
- * success = AsciiToInputEvent(ascii, inputevent, keymap)
- * ULONG AsciiToInputEvent(ULONG, struct InputEvent *, struct KeyMap *)
- *
- * FUNCTION
- * This function tries to generate an input event that, when sent
- * to the input handler, will generate the specified ascii code.
- *
- * INPUTS
- * ascii - the ascii code to be generated by the constructed
- * input event.
- *
- * inputevent - the input event that will be filled will the
- * appropriate values to generate the given ascii code.
- *
- * keymap - the keymap that the input event will be reverse-
- * engineered from.
- *
- *
- * RESULT
- * success - a boolean value indicating whether the reverse-
- * engineering was successful.
- *
- * NOTE
- * The ascii code must be available in the given keymap to be
- * generatable. Ascii values between 128 and 160 are usually
- * not available with normal keymaps.
- *
- * SEE ALSO
- * RawKeyConvert(), V36 keymap.library/MapANSI().
- */
-
- ULONG AsciiToInputEvent(ascii, ie, km)
- ULONG ascii;
- register struct InputEvent *ie;
- struct KeyMap *km;
- {
- struct HalfMap *hm;
-
- ie->ie_Class = IECLASS_RAWKEY;
- ie->ie_Qualifier = 0;
- ie->ie_EventAddress = 0;
-
- /* Some ascii values has to be treated separately
- since some programs know the difference between
- for example CTRL-M and RETURN. */
- {
- WORD code = 0;
-
- switch(ascii)
- {
- case 0x08: /* backspace */
- code = 0x41;
- break;
- case '\t': /* tab */
- code = 0x42;
- break;
- case 0x0D: /* return */
- code = 0x44;
- break;
- case 0x1B: /* esc */
- code = 0x45;
- break;
- case 0x7F: /* del */
- code = 0x46;
- break;
- }
-
- if (code) {
- ie->ie_Code = code;
- return 1;
- }
- }
-
- hm = (struct HalfMap *)&km->km_LoKeyMapTypes;
- if (BuildEvent((UBYTE)ascii, hm, 64, ie, km)) {
- return 1; /* Key found in LoKeyMap */
- }
- hm = (struct HalfMap *)&km->km_HiKeyMapTypes;
- if (BuildEvent((UBYTE)ascii, hm, 56, ie, km)) {
- ie->ie_Code += 64; /* Don't forget that we're in the hi keymap */
- return 1; /* Key found in HiKeyMap */
- }
- return 0; /* No luck */
- }
-